package com.zac.pomodoro

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.detectDragGesturesAfterLongPress
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.tencent.mmkv.MMKV
import com.zac.pomodoro.bean.Task
import com.zac.pomodoro.ui.theme.PomodoroTheme
import com.zac.pomodoro.viewmodel.ViewModel
import kotlinx.coroutines.launch

class TaskListActivity : ComponentActivity() {

    companion object {
        const val KEY_JOBS = "POMODORO_JOBS"
    }

    private val viewModel: ViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        enableEdgeToEdge()

        setContent {
            PomodoroTheme {
                var timeText by remember { mutableStateOf("20") }
                var text by remember { mutableStateOf("") }
                var showHint by remember { mutableStateOf(true) }
                viewModel.taskList.addAll(loadJobs())
                Scaffold(modifier = Modifier.fillMaxSize()) { _ ->
                    Column(
                        Modifier
                            .statusBarsPadding()
                            .padding(horizontal = 16.dp),
                        verticalArrangement = Arrangement.spacedBy(8.dp)
                    ) {

                        Text(
                            text = "Tasks List",
                            modifier = Modifier.fillMaxWidth(),
                            textAlign = TextAlign.Center
                        )

                        Box {
                            BasicTextField(
                                text,
                                textStyle = TextStyle(textAlign = TextAlign.Start),
                                onValueChange = { newText -> text = newText },
                                modifier = Modifier
                                    .fillMaxWidth()
                                    .border(
                                        width = 2.dp,
                                        color = Color.Black,
                                        shape = RoundedCornerShape(8.dp)
                                    )
                                    .padding(10.dp)
                                    .defaultMinSize(minHeight = 100.dp)
                                    .onFocusChanged {
                                        showHint = !(it.hasFocus)
                                    },
                            )
                            if (showHint) {
                                Text(
                                    "Create A Task",
                                    color = Color.Gray,
                                    modifier = Modifier.padding(10.dp)
                                )
                            }
                        }
                        Row(
                            horizontalArrangement = Arrangement.Center,
                            verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier
                                .fillMaxWidth()
                                .height(50.dp)
                        ) {

                            Box(
                                modifier = Modifier
                                    .width(100.dp)
                                    .fillMaxHeight()
                                    .border(
                                        width = 2.dp,
                                        color = Color.Black,
                                        shape = RoundedCornerShape(8.dp)
                                    )
                                    .padding(10.dp),
                                contentAlignment = Alignment.Center
                            ) {
                                BasicTextField(
                                    timeText,
                                    textStyle = TextStyle(textAlign = TextAlign.Center),
                                    onValueChange = { newText ->
                                        timeText = newText.filter { it.isDigit() }
                                    },
                                    keyboardOptions = KeyboardOptions(
                                        keyboardType = KeyboardType.Number,
                                        imeAction = ImeAction.Done
                                    )
                                )
                            }
                            Spacer(modifier = Modifier.width(10.dp))
                            Box(
                                modifier = Modifier
                                    .fillMaxHeight(),
                                contentAlignment = Alignment.Center
                            ) {
                                Text(
                                    text = "Minute",
                                    fontStyle = FontStyle.Normal,
                                    color = Color.Black,
                                )
                            }
                            Spacer(modifier = Modifier.width(10.dp))
                            Box(
                                modifier = Modifier
                                    .width(100.dp)
                                    .fillMaxHeight()
                                    .background(
                                        color = Color.Gray,
                                        shape = RoundedCornerShape(8.dp)
                                    )
                                    .clickable {
                                        if (text.isBlank()) {
                                            Toast
                                                .makeText(
                                                    this@TaskListActivity,
                                                    "Please enter job description",
                                                    Toast.LENGTH_SHORT
                                                )
                                                .show()
                                            return@clickable
                                        }
                                        if (timeText.isBlank()) {
                                            Toast
                                                .makeText(
                                                    this@TaskListActivity,
                                                    "Please schedule time for this job",
                                                    Toast.LENGTH_SHORT
                                                )
                                                .show()
                                            return@clickable
                                        }

                                        viewModel.taskList.add(
                                            Task(
                                                System.currentTimeMillis(),
                                                text,
                                                timeText.toLong()
                                            )
                                        )
                                        MMKV
                                            .defaultMMKV()
                                            .encode(KEY_JOBS, Gson().toJson(viewModel.taskList))
                                    },
                                contentAlignment = Alignment.Center
                            ) {
                                Text(
                                    text = "Create",
                                    fontStyle = FontStyle.Normal,
                                    color = Color.White,

                                    )
                            }

                        }
                        TaskList(viewModel.taskList)
                    }
                }
            }
        }
    }

    private fun loadJobs(): MutableList<Task> {
        val jobsCacheString = MMKV.defaultMMKV().decodeString(KEY_JOBS)
        val type = object : TypeToken<MutableList<Task>>() {}.type
        return Gson().fromJson<MutableList<Task>?>(jobsCacheString, type).takeIf { it != null }
            ?: mutableListOf()
    }

    @Composable
    fun TaskList(taskList: MutableList<Task>) {
        var currentPosition by remember { mutableStateOf(Offset.Zero) }
        val scope = rememberCoroutineScope()
        var draggedItem by remember { mutableStateOf<Task?>(null) }
        var selectItem by remember { mutableStateOf<Task?>(null) }
        val itemHeights = remember { mutableStateMapOf<Long, Int>() }
        var dragItemYPosition by remember { mutableFloatStateOf(0f) }
        var dragItemYPositionDiff by remember { mutableFloatStateOf(0f) }
        var dragStartOffset by remember { mutableFloatStateOf(0f) }
        var deleteItem by remember { mutableStateOf<Task?>(null) }
        var editItem by remember { mutableStateOf<Task?>(null) }
        var newDescription by remember { mutableStateOf<String?>(null) }
        var editTimeText by remember { mutableStateOf<String?>(null) }
        Box(modifier = Modifier.pointerInput(Unit) {
            detectTapGestures(
                onLongPress = {
                    dragItemYPosition = it.y - dragItemYPositionDiff
                    Log.e(
                        "zac",
                        "onLongPress :dragItemYPosition = $dragItemYPosition"
                    )
                }
            )
        }) {
            LazyColumn(
                modifier = Modifier.fillMaxSize(),
                verticalArrangement = Arrangement.spacedBy(1.dp)
            ) {
                itemsIndexed(items = taskList, key = { _, item -> item.id }) { index, item ->
                    Column {
                        Box(
                            modifier = Modifier
                                .background(
                                    if (draggedItem?.id == item.id) {
                                        Color.Transparent
                                    } else {
                                        Color.White
                                    }
                                )
                        ) {
                            Row(
                                verticalAlignment = Alignment.CenterVertically,
                                modifier = Modifier
                                    .height(40.dp)
                            ) {
                                Text(
                                    text = item.description,
                                    modifier = Modifier
                                        .weight(1f)
                                        .animateContentSize()
                                        .clickable {
                                            if (item.running) {
                                                Toast.makeText(
                                                    this@TaskListActivity,
                                                    "This task is already being executed and cannot be operated",
                                                    Toast.LENGTH_SHORT
                                                ).show()
                                                return@clickable
                                            }
                                            selectItem = item
                                        })

                                Row(
                                    verticalAlignment = Alignment.CenterVertically,
                                    modifier = Modifier.fillMaxHeight()
                                ) {
                                    Text(text = "${item.timeMin}'")
                                    Icon(
                                        painterResource(R.drawable.move),
                                        "",
                                        modifier = Modifier
                                            .fillMaxHeight()
                                            .padding(10.dp)
                                            .onGloballyPositioned {
                                                itemHeights[item.id] = it.size.height
                                            }
                                            .pointerInput(Unit) {
                                                detectDragGesturesAfterLongPress(
                                                    onDragStart = {
                                                        dragItemYPositionDiff = it.y
                                                        draggedItem = item
                                                        currentPosition = Offset(0f, -it.y)
                                                        dragStartOffset = it.y


                                                    },
                                                    onDragEnd = {
                                                        Log.e(
                                                            "zac",
                                                            "onDragEnd"
                                                        )
                                                        dragStartOffset = 0f
                                                        draggedItem = null
                                                        currentPosition = Offset.Zero
                                                    },
                                                    onDrag = { change, dragAmount ->
                                                        change.consume()
                                                        currentPosition += dragAmount
                                                        dragItemYPosition += dragAmount.y
                                                        scope.launch {
                                                            val targetIndex = calculateNewIndex(
                                                                item,
                                                                taskList,
                                                                currentPosition.y,
                                                                itemHeights,
                                                            )
                                                            Log.e(
                                                                "zac",
                                                                "targetIndex = $targetIndex itemIndex = ${item.id}"
                                                            )
                                                            if (targetIndex != taskList.indexOf(
                                                                    item
                                                                )
                                                            ) {
                                                                taskList.remove(item)
                                                                taskList.add(targetIndex, item)
                                                                currentPosition = Offset.Zero
                                                            }
                                                        }


                                                    })

                                            }

                                    )
                                }
                            }

                        }

                        if (index < taskList.size - 1) {
                            HorizontalDivider(color = Color.LightGray, thickness = 1.dp)
                        }
                    }
                }

            }
            // 悬浮的拖动项
            draggedItem?.let { item ->
                Log.e("zac", "draggedItem = ${item.description}")
                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = Modifier
                        .offset {
                            IntOffset(
                                x = 0,
                                y = dragItemYPosition.toInt()
                            )
                        }
                        .background(color = Color.Gray)
                        .height(40.dp)
                ) {
                    Text(
                        text = item.description,
                        modifier = Modifier
                            .weight(1f)
                            .animateContentSize()
                    )

                    Row(
                        verticalAlignment = Alignment.CenterVertically,
                        modifier = Modifier.fillMaxHeight()
                    ) {
                        Text(text = "${item.timeMin}'")
                        Icon(
                            painterResource(R.drawable.move),
                            "",
                            modifier = Modifier
                                .fillMaxHeight()
                                .padding(10.dp)

                        )
                    }
                }
            }
            if (selectItem != null) {
                Dialog(onDismissRequest = { selectItem = null }) {
                    Column(
                        modifier = Modifier
                            .width(400.dp)
                            .background(color = Color.Gray),
                        horizontalAlignment = Alignment.CenterHorizontally

                    ) {
                        Box(
                            modifier = Modifier
                                .defaultMinSize(minHeight = 44.dp)
                                .background(Color.White)
                                .fillMaxWidth()
                                .align(Alignment.CenterHorizontally)
                                .padding(horizontal = 15.dp, vertical = 12.dp)
                        ) {
                            Text(
                                selectItem!!.description,
                                modifier = Modifier.align(Alignment.Center)
                            )
                        }
                        Spacer(modifier = Modifier.height(1.dp))
                        Box(
                            modifier = Modifier
                                .defaultMinSize(minHeight = 44.dp)
                                .align(Alignment.CenterHorizontally)
                                .background(Color.White)
                                .fillMaxWidth()
                                .clickable {
                                    viewModel.taskList.remove(selectItem)
                                    viewModel.taskList.add(0, selectItem!!)
                                    selectItem = null
                                }
                                .padding(horizontal = 15.dp, vertical = 12.dp)
                        ) {
                            Text(
                                "Put this task at the top",
                                modifier = Modifier.align(Alignment.Center)
                            )
                        }

                        Spacer(modifier = Modifier.height(1.dp))
                        Box(
                            modifier = Modifier
                                .defaultMinSize(minHeight = 44.dp)
                                .align(Alignment.CenterHorizontally)
                                .fillMaxWidth()
                                .clickable {
                                    editItem = selectItem
                                }
                                .padding(horizontal = 15.dp, vertical = 12.dp)
                        ) {
                            Text("Edit", modifier = Modifier.align(Alignment.Center))
                        }
                        Spacer(modifier = Modifier.height(1.dp))
                        Box(
                            modifier = Modifier
                                .defaultMinSize(minHeight = 44.dp)
                                .align(Alignment.CenterHorizontally)
                                .fillMaxWidth()
                                .clickable {
                                    deleteItem = selectItem
                                }
                                .background(Color.Red)
                                .padding(horizontal = 15.dp, vertical = 12.dp)
                        ) {
                            Text("Delete", modifier = Modifier.align(Alignment.Center))
                        }


                    }
                }
            }

            if (deleteItem != null) {
                Dialog(onDismissRequest = { deleteItem = null }) {

                    Column(
                        modifier = Modifier
                            .background(color = Color.White)
                            .clip(
                                shape = RoundedCornerShape(8.dp)
                            )
                    ) {
                        Box(modifier = Modifier.padding(horizontal = 12.dp, vertical = 10.dp)) {
                            Text(
                                "This Task will be deleted!",
                                style = TextStyle(color = Color.Black)
                            )
                        }
                        Spacer(
                            Modifier
                                .fillMaxWidth()
                                .height(1.dp)
                                .background(color = Color.Gray)
                        )
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier.height(48.dp)
                        ) {
                            Text(
                                "Cancel", modifier = Modifier
                                    .weight(1f)
                                    .clickable {
                                        deleteItem = null
                                    }
                            )
                            Spacer(
                                Modifier
                                    .fillMaxHeight()
                                    .width(1.dp)
                                    .background(color = Color.Gray)
                            )
                            Text(
                                "DELETE", modifier = Modifier
                                    .weight(1f)
                                    .clickable {
                                        viewModel.taskList.remove(deleteItem)
                                        deleteItem = null
                                        selectItem = null
                                    }
                            )


                        }
                    }

                }
            }
            if (editItem != null) {
                Dialog(onDismissRequest = { editItem = null }) {
                    Column(
                        modifier = Modifier
                            .background(color = Color.White)
                            .clip(
                                shape = RoundedCornerShape(8.dp)
                            )
                    ) {
                        Box(
                            modifier = Modifier
                                .fillMaxWidth()
                                .height(50.dp)
                                .border(
                                    width = 2.dp,
                                    color = Color.Black,
                                    shape = RoundedCornerShape(8.dp)
                                )
                                .padding(10.dp),
                            contentAlignment = Alignment.Center
                        ) {
                            BasicTextField(
                                value = newDescription ?: editItem!!.description,
                                onValueChange = {
                                    newDescription = it
                                }
                            )
                        }
                        Spacer(
                            Modifier
                                .fillMaxWidth()
                                .height(1.dp)
                                .background(color = Color.Gray)
                        )
                        Row(
                            verticalAlignment = Alignment.CenterVertically,
                            modifier = Modifier.height(48.dp)
                        ) {
                            Text(
                                "Time", modifier = Modifier
                                    .weight(1f)
                                    .clickable {
                                        deleteItem = null
                                    }
                            )
                            Spacer(
                                Modifier
                                    .fillMaxHeight()
                                    .width(1.dp)
                                    .background(color = Color.Gray)
                            )
                            Box(
                                modifier = Modifier
                                    .weight(1f)
                                    .height(50.dp)
                                    .border(
                                        width = 2.dp,
                                        color = Color.Black,
                                        shape = RoundedCornerShape(8.dp)
                                    )
                                    .padding(10.dp),
                                contentAlignment = Alignment.Center
                            ) {
                                BasicTextField(
                                    editTimeText ?: "",
                                    textStyle = TextStyle(textAlign = TextAlign.Center),
                                    onValueChange = { newText ->
                                        editTimeText = newText.filter { it.isDigit() }
                                    },
                                    keyboardOptions = KeyboardOptions(
                                        keyboardType = KeyboardType.Number,
                                        imeAction = ImeAction.Done
                                    )
                                )
                            }


                        }

                        Box(
                            contentAlignment = Alignment.Center,
                            modifier = Modifier
                                .fillMaxWidth()
                                .height(50.dp)
                                .clickable {
                                    val itemInList = viewModel.taskList.find {
                                        it.id == editItem!!.id
                                    }


                                    if (editTimeText.isNullOrEmpty()) {
                                        Toast.makeText(
                                            this@TaskListActivity,
                                            "Please input time in minute",
                                            Toast.LENGTH_SHORT
                                        ).show()
                                        return@clickable
                                    }

                                    if (newDescription.isNullOrEmpty()) {
                                        Toast.makeText(
                                            this@TaskListActivity,
                                            "Please input task content",
                                            Toast.LENGTH_SHORT
                                        ).show()
                                        return@clickable
                                    }
                                    itemInList?.timeMin = editTimeText!!.toLong()
                                    itemInList?.description = newDescription!!
                                    editItem = null
                                    selectItem = null

                                }
                        ) {
                            Text("保存")
                        }
                    }

                }
            }
        }
    }


    private fun calculateNewIndex(
        item: Task,
        itemList: List<Task>,
        drawOffsetY: Float,
        itemHeights: Map<Long, Int>,
    ): Int {
        val index = itemList.indexOf(item)
        var accumulatedHeight = 0
        var targetIndex = index

        if (drawOffsetY < 0) {
            for (i in index downTo 0) {
                accumulatedHeight -=
                    (itemHeights[itemList[i].id] ?: 0).toInt()

                if (drawOffsetY < accumulatedHeight) {
                    Log.e(
                        "zac",
                        "move up---accumulatedHeight=$accumulatedHeight"
                    )
                    targetIndex = i
                } else break
            }
        } else if (drawOffsetY > 0) {
            for (i in index until itemList.size) {
                accumulatedHeight +=
                    (itemHeights[itemList[i].id] ?: 0).toInt()

                if (drawOffsetY > accumulatedHeight) {
                    Log.e(
                        "zac",
                        "move down---accumulatedHeight=$accumulatedHeight"
                    )
                    targetIndex = i
                } else break
            }
        }
        Log.e(
            "zac",
            "---targetIndex=$targetIndex"
        )
        return targetIndex.coerceIn(0, itemList.size - 1)
    }

    override fun onDestroy() {
        super.onDestroy()

        MMKV.defaultMMKV().encode(KEY_JOBS, Gson().toJson(viewModel.taskList))
    }


}